import router from './router' // asyncRouterMap  动态路由
import store from './store'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // getToken from cookie
import { Message } from 'element-ui'
NProgress.configure({ showSpinner: false }) // NProgress Configuration

// 取出某一子应用第一个显示页面，需要根据菜单类型
function getFirstPath(child) {
  if (!child.noDisplay && !child.hidden) {
    let path = child.path
    if (child.children && child.children.length) {
      path = getFirstPath(child.children[0])
    }
    return path
  }
}

// 权限判断函数，每次访问都做访问控制，耗费性能
// function hasPermission(roles, to) {
//   // 与所有应用作匹配 判断 noDisplay
//   for (let i = 0; i < roles.length; i++) {
//     if (roles[i].path === to.path) {
//       if (roles[i].noDisplay) {
//         return false
//       }
//     } else {
//       if (roles[i].children && roles[i].children.length) {
//         let flag = hasPermission(roles[i].children, to)
//         if (typeof flag !== 'undefined') return flag
//       }
//     }
//   }
// }

const whiteList = ['/login']  // 权限白名单
const setTitle = () => {
  document.title = ''
}
/**
 * 路由拦截
 */
router.beforeEach(async (to, from, next) => {
  setTitle(to.meta)
  NProgress.start()
  // 是否登录
  if (getToken()) {
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      // 取缓存的用户信息
      if (store.getters.userInfo) {
        // 校验是否有当前路由权限
        // if (hasPermission(store.getters.addRouters, to) === false) {
        //   next({ path: '/portal-error401', replace: true })
        // } else {
          // 因为微前端原因 默认进入需调第一个子路由的第一个页面
          if (to.path === '/') {
            // 取出第一个菜单的权限和菜单
            const { appPrefix, appMenus } = store.getters.subApp[0]
            sessionStorage.setItem('subAppPrefix', appPrefix, true)
            sessionStorage.setItem('refreshApp', appPrefix, true)
            // 根据子应用生成，左侧菜单
            await store.dispatch('generateRoutes', appMenus)
            // 根据menu id生成可访问的路由表
            router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
            store.dispatch('setShowTrue')  // 解决 登录时 动态路由未加载情况 
            let path
            for (let i = 0; i < appMenus.length; i ++) {
              path = getFirstPath(appMenus[i])
              if (path) {
                break
              }
            }
            // 点击 logo跳转首页的拦截
            if (path === from.path) {
              NProgress.done()
              return
            }
            next({ path, replace: true })
          } else {
            next()
          }
        // }
      } else {
        try {
          // 判断当前用户是否已拉取完user_info信息，localStorage进行用户信息缓存
          const res = await store.dispatch('getUserInfo')
          // 新出单独查询
          const { menu } = res
          // 生成路由转换
          await store.dispatch('generateSubApp', menu)
          // 左侧动态路由
          const subAppPrefix = sessionStorage.getItem('subAppPrefix', true)
          let appMenus, index, redirect
          const subApp = store.getters.subApp
          if (subAppPrefix) {
            index = subApp.findIndex(item => item.appPrefix === subAppPrefix)
            appMenus = subApp[index].appMenus
          } else {
            // 排除 登录页跳过来的 携带参数情况，登录页过来 携带 redirect参数
            if (from.path === '/login' && from.query.redirect) {
              redirect = '/' + from.query.redirect.split('/')[1]
              index = subApp.findIndex(item => item.appPrefix === redirect)
              if (index === -1) {
                // 如果 redirect 不属于子应用 路由体系的话
                redirect = subApp[0].appPrefix
                appMenus = subApp[0].appMenus
              } else {
                appMenus = subApp[index].appMenus
              }
            } else {
              // 登录页过来 不携带 redirect参数 默认取第一项
              index = -1
              redirect = subApp[0].appPrefix
              appMenus = subApp[0].appMenus
            }
            sessionStorage.setItem('subAppPrefix', redirect, true)
          }
          await store.dispatch('generateRoutes', appMenus)
          // 根据menu id生成可访问的路由表
          router.addRoutes(store.getters.addRouters) // 动态添加可访问路由表
          store.dispatch('setShowTrue')  // 解决 登录时 动态路由未加载情况 
          // 改变跳转地址 防止首次登录跳转 / 和 /portal-404 页面
          if (index === -1) {
            let path, appMenus = subApp[0].appMenus
            for (let i = 0; i < appMenus.length; i ++) {
              path = getFirstPath(appMenus[i])
              if (path) break
            }
            next({ path, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
          } else {
            next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
          }
        } catch (error) {
          store.dispatch('fedLogOut').then(() => {
            Message.error({
              message: error || '验证错误， 请重新登录',
              duration: 3000,
              onClose: () => {
                next({ path: '/' })
              }
            })
          })
        }
      }
    }
  } else {
    /* has no token*/
    if (whiteList.includes(to.path)) {
      // 在免登录白名单，直接进入
      next()
    } else {
      next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
      // token失效之后 无法重定向至 登录页
      if (to.path !== '/' && from.path !== '/') {
        Message.error({
          message: '验证错误， 请重新登录',
          duration: 3000,
          onClose: () => {
            location.reload()
          }
        })
      }
      NProgress.done()
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})